package com.caocaog.market.controller;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.caocaog.market.annotation.IgnoreAuth;
import com.caocaog.market.entity.*;
import com.caocaog.market.pay.UnionPay;
import com.caocaog.market.pay.syb.dto.SybDto;
import com.caocaog.market.pay.wxpay.BDPay;
import com.caocaog.market.service.*;
import com.caocaog.market.vo.DistanceVo;
import com.caocaog.market.vo.OrderForOneVo;
import com.caocaog.market.vo.ShopInfoVo;
import com.caocaog.market.vo.ShopVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.util.oConvertUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.*;

/**
 * 商品订单api-曹操来了
 * 曹操来了和送大侠代码初始用的是同一套业务逻辑
 * 1.暂时和曹操来了逻辑一致 生成订单号/退款单号区别标识
 * 2.购物车逻辑一致
 * 3.下单逻辑一致
 * 4.支付/支付回调用的是一套逻辑,未区分
 * 5.门店商品逻辑一致
 * 6.支付后结算 ,向跑腿推单子逻辑一致
 * 如上1,2,3,4,5,6业务功能修改,service层已和送大侠分开,如果修改mapper层
 * 或者 如果修改逻辑 请勿修改原代码 可考虑采用重载和重写的方法 知悉~
 */
@Slf4j
@RestController
@RequiredArgsConstructor
@Api(value = "orderApi", tags = "API商品订单")
@RequestMapping("/api/order")
public class ApiOrderController extends BaseController {

    @Autowired
    private IOrderBaseService orderBaseService;
    @Autowired
    private IOrderPayService orderPayService;
    @Autowired
    private IOrderRefundService orderRefundService;
    @Autowired
    private IMemberAddressService memberAddressService;
    @Autowired
    private UnionPay unionPay;
    @Autowired
    private BDPay bdPay;
    @Autowired
    private IPageViewService pageViewService;

    @AutoLog(value = "设备访问量同步")
    @ApiOperation(value = "设备访问量同步", notes = "设备访问量同步", response = PageView.class)
    @PostMapping(value = "/miniAppViewSave")
    public Result<?> miniAppViewSave(@RequestBody PageView pageView) {

        Member member = verifyUserForApp();
        if (oConvertUtils.isEmpty(pageView.getIp()) || oConvertUtils.isEmpty(pageView.getIsAndroid())) {
            return Result.error("参数错误");
        }
        if (pageView.getIsAndroid() != 0 && pageView.getIsAndroid() != 1) {
            return Result.error("参数错误");
        }
        pageView.setMemberId(member.getId());
        pageView.setCreateTime(new Date());
        pageView.setCreateBy(member.getNickName());
        Boolean result = pageViewService.save(pageView);
        return Result.OK(result ? "操作成功" : "操作失败");
    }

    /**
     * 用户黑名单
     */
    private static final Set<String> Blacklist = new HashSet<String>() {{
        add("1523488348491935747"); // 18829454856
        add("1567516767927910403"); // 18829450385
    }};


    @AutoLog(value = "单商品下订单")
    @ApiOperation(value = "单商品下订单", notes = "单商品下订单")
    @PostMapping(value = "/OrderForOne")
    public Result<?> OrderForOne(@RequestBody OrderForOneVo vo) {

        Member member = verifyUserForApp();
        log.info("单商品下订单");
        log.info("vo = " + vo);
        log.info("member = " + member);

        if (!member.getId().equals(vo.getMemberId()) || Blacklist.contains(vo.getMemberId())) {
            return Result.error("暂无权限操作~");
        } else if (oConvertUtils.isEmpty(vo.getPayMoney()) ||
                oConvertUtils.isEmpty(vo.getShopId())) {
            return Result.error("参数错误");
        } else {
            return orderBaseService.add(vo, member);
        }
    }

    @AutoLog(value = "获取合计 配送费 打包费 距离")
    @ApiOperation(value = "获取合计 配送费 打包费 距离")
    @PostMapping(value = "/getOrderOfPrice")
    public Result<?> getSumPrice(@RequestBody OrderForOneVo vo) {

        Member member = verifyUserForApp();
        if (!member.getId().equals(vo.getMemberId())) {
            return Result.error("暂无权限操作~");
        } else if (oConvertUtils.isEmpty(vo.getShopId())) {
            return Result.error("参数错误");
        } else {
            return orderBaseService.getSumPrice(vo);
        }
    }

    @AutoLog(value = "订单列表")
    @ApiOperation(value = "订单列表", notes = "params: memberId必传 \n type:类型1：外卖 2：自提 status:-3:退款成功" +
            "\n type和status都不传时,默认查询该用户的所有订单 ", response = OrderBase.class)
    @GetMapping(value = "/selectOrderListForMember")
    public Result<?> selectOrderListForMember(OrderBase orderBase,
                                              @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                              @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize) {
        Member member = verifyUserForApp();
        if (!member.getId().equals(orderBase.getMemberId())) {
            return Result.error("暂无权限操作~");
        }
        // 全部 配送单 自提单 退款
        IPage<OrderBase> orderBaseList = orderBaseService.selectOrderListForMember(orderBase, pageNo, pageSize);
        log.info("订单列表" + orderBaseList.getRecords().size());
        return Result.OK(orderBaseList);
    }

    @IgnoreAuth
    @AutoLog(value = "订单列表-商家端")
    @ApiOperation(value = "订单列表-商家端", notes = "", response = OrderBase.class)
    @GetMapping(value = "/selectOrderListForMerchant")
    public Result<?> selectOrderListForMerchant(OrderBase orderBase,
                                                @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                                @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize) {
        if (oConvertUtils.isEmpty(orderBase.getMerchantId()) && oConvertUtils.isEmpty(orderBase.getShopId())) {
            return Result.error("参数错误~");
        }
        // 全部 配送单 自提单 退款
        IPage<OrderBase> orderBaseList = orderBaseService.selectOrderListForMerchant(orderBase, pageNo, pageSize);
        log.info("订单列表" + orderBaseList.getRecords().size());
        return Result.OK(orderBaseList);
    }

    @IgnoreAuth
    @AutoLog(value = "获取订单其他信息")
    @ApiOperation(value = "获取订单其他信息", notes = "获取订单其他信息")
    @GetMapping(value = "/selectOrderInfo")
    public Result<?> selectOrderInfo(@RequestParam("id") String id) {

        return Result.OK(orderBaseService.selectOrderInfo(id));
    }

    /**
     * 原版的通联支付
     * @param sybDto 支付参数
     * @return 支付结果
     */
    @AutoLog(value = "微信小程序订单支付")
    @ApiOperation(value = "微信小程序订单支付")
    @PostMapping(value = "/orderPayUnion")
    public Result<?> orderPay(@RequestBody SybDto sybDto) {
        Member member = verifyUserForApp();
        String orderId = sybDto.getOrderId();
        OrderBase orderBase = orderBaseService.getById(orderId);

        if (null == orderBase) {
            return Result.error("参数错误,订单不存在~");
        }
        if (!orderBase.getStatus().equals("0")) {
            String errorMsg = "参数错误,订单不是待支付状态:" + orderBase.getOrderNo() + "-" + orderBase.getStatus();
            log.error(errorMsg);
            return Result.error(errorMsg);
        }
        log.info(member.toString());
        sybDto.setReqSn(orderBase.getOrderNo());
        sybDto.setAcct(member.getWxOpenid());
        orderBaseService.buildThisOrderMerchantPay(orderBase,sybDto);
        return unionPay.payUnion(sybDto);
    }

    /**
     * 创建微信支付的订单
     * @param orderId 订单ID
     * @param payMoney 支付金额
     * @param type 小程序类型
     * @return 支付结果
     */
    @AutoLog(value = "微信小程序订单支付")
    @ApiOperation(value = "微信小程序订单支付")
    @PostMapping(value = "/orderPay")
    public Result<?> orderPay(@ApiParam("orderId") @RequestParam("orderId") String orderId,
                              @ApiParam("支付金额") @RequestParam("payMoney") String payMoney,
                              @ApiParam("小程序类型 0微信 1字节 默认0") @RequestParam(value = "type", required = false) Integer type) {
        Member member = verifyUserForApp();
        OrderBase orderBase = orderBaseService.getById(orderId);
        if (null == orderBase) {
            return Result.error("参数错误,订单不存在~");
        }
        if (!orderBase.getStatus().equals("0")) {
            String errorMsg = "参数错误,订单不是待支付状态:" + orderBase.getOrderNo() + "-" + orderBase.getStatus();
            log.error(errorMsg);
            return Result.error(errorMsg);
        }
        OrderPay orderPay = orderPayService.getOne(new QueryWrapper<OrderPay>().eq("order_id", orderId));
        if (null == orderPay) {
            return Result.error("参数错误,订单异常~");
        }
        if (new BigDecimal(orderPay.getPayAmount()).compareTo(new BigDecimal("0.01")) < 0) {
            log.error("payAmount:" + orderPay.getPayAmount());
            return Result.error("参数错误,支付金额异常~");
        }
        if (new BigDecimal(orderPay.getPayAmount()).compareTo(new BigDecimal(payMoney)) != 0) {
            return Result.error("参数错误，支付金额与源订单不匹配~");
        }
        orderPay.setPayTime(new Date());
        orderPayService.updateById(orderPay);

        log.info(member.toString());

        if (Objects.isNull(type) || type == 0) {
            return unionPay.payWx(orderId, "", "大豫仓-订单支付", null, member.getWxOpenid());
        } else {
            return Result.OK(unionPay.ttPay(orderId, "大豫仓-订单支付", "大豫仓-订单支付", member.getWxOpenid()));
        }
    }

    // 取消订单
    @AutoLog(value = "取消订单")
    @ApiOperation(value = "取消订单-待付款的可取消")
    @GetMapping(value = "/cancelOrder")
    public Result<?> cancelOrder(@ApiParam("orderId") @RequestParam("orderId") String orderId) {
        Member member = verifyUserForApp();
        OrderBase orderBase = orderBaseService.getById(orderId);
        if (null == orderBase) {
            return Result.error("参数错误,订单不存在~");
        }
        if (!orderBase.getStatus().equals("0")) {
            String errorMsg = "参数错误,订单不是待付款状态:" + orderBase.getOrderNo() + "-" + orderBase.getStatus();
            log.error(errorMsg);
            return Result.error(errorMsg);
        }
        return orderBaseService.cancelOrder(orderBase, member);

    }


    @AutoLog(value = "退款")
    @ApiOperation(value = "退款订单")
    @PostMapping(value = "/refundOrder")
    public Result<?> refundOrder(@RequestBody OrderRefund orderRefund) {
        log.info("退款订单====>" + orderRefund.toString());
        Member member = verifyUserForApp();
        if (!member.getWxOpenid().equals(orderRefund.getOpenid())) {
            return Result.error("参数错误~");
        }
        OrderBase orderBase = orderBaseService.getOne(new QueryWrapper<OrderBase>().eq("order_no", orderRefund.getOrderNo()).last(" limit 1 "));
        if (null == orderBase) {
            return Result.error("参数错误,订单不存在~");
        }
        if (Integer.parseInt(orderBase.getStatus()) == -2) {
            OrderRefund orderRefund1 = orderRefundService.getOne(new QueryWrapper<OrderRefund>()
                    .eq("order_id", orderRefund.getOrderId()));
            String errorMsg = "";
            if (null != orderRefund1 && orderRefund1.getAudit() != 2) {
                if (orderRefund1.getAudit() == 1) {
                    errorMsg = "您的订单退款已审核通过，请后续注意退款到账";
                } else {
                    errorMsg = "您的订单退款正在审核中,如有问题请联系商家";
                }

                log.error(errorMsg);
                return Result.error(errorMsg);
            }
        }
        if (orderBase.getStatus().equals("-3")) {
            return Result.error("退款已完成");
        }
        if (Integer.parseInt(orderBase.getStatus()) < 1) {
            String errorMsg = "参数错误,订单无法申请退款:" + orderBase.getOrderNo() + "-" + orderBase.getStatus();
            log.error(errorMsg);
            return Result.error(errorMsg);
        }
        // 判断 结算状态 bill  mkBillBaseService
        /*MkBillBase mkBillBase = mkBillBaseService.findBillIsExist(orderBase.getOrderNo());
        if (oConvertUtils.isNotEmpty(mkBillBase) && mkBillBase.getPayStatus() != 1) {
            return Result.error("不能申请退款了哟，如有问题，请联系店家～");
        }*/

        return orderBaseService.refundOrder(orderRefund, member, orderBase);
    }

    @ApiOperation(value = "字节小程序支付结果查询")
    @GetMapping(value = "/bdPayResult")
    public JSONObject getBDPayResult(@RequestParam String orderNo) {
        return bdPay.ttPayResult(orderNo);
    }

    // 获取配送费  计算两个经纬度(用户地址和店铺)之间的距离
    @AutoLog(value = "获取配送费")
    @ApiOperation(value = "获取配送费 获取默认常用地址", notes = "params:1. gpsTo和shopId amount必传  \n 2.memberId和 gpsfrom 都不传时,返回用户的一个常用地址,距离和配送费")
    @PostMapping(value = "/getDeliveryAmount")
    public Result<?> getDeliveryAmount(@RequestBody DistanceVo vo) {
        Member member = verifyUserForApp();
        log.info("获取配送费");
        log.info("vo = " + vo);
        log.info("member = " + member);

        if (oConvertUtils.isEmpty(vo.getGpsToLat())
                || oConvertUtils.isEmpty(vo.getGpsFromLng())
                || oConvertUtils.isEmpty(vo.getShopId())
                || oConvertUtils.isEmpty(vo.getAmount())) {
            return Result.error("参数错误");
        }
        if (oConvertUtils.isEmpty(vo.getMemberId())) {
            vo.setMemberId(member.getId());
        }

        DistanceVo distanceVo = orderBaseService.getDeliveryAmount(vo);

        return Result.OK(distanceVo);
    }

    @IgnoreAuth
    @AutoLog(value = "周边店铺 周边好物")
    @ApiOperation(value = "周边店铺 周边好物", notes = "/{type}/{lat}/{lng}\n 1.type=1周边店铺 type=2周边好物 \n ", response = ShopVo.class)
    @GetMapping(value = "/goodThingsAround")
    public Result<?> goodThingsAround(@RequestParam(required = false) String siteId,
                                      @RequestParam int type,
                                      @RequestParam String lat,
                                      @RequestParam String lng) {

        return orderBaseService.goodThingsAround(siteId, type, lat, lng);
    }

    @IgnoreAuth
    @AutoLog(value = "首页-店铺推荐")
    @ApiOperation(value = "首页-店铺推荐", notes = "param 分站id", response = ShopVo.class)
    @GetMapping(value = "/DayRecommend")
    public Result<?> DayRecommend(@RequestParam("siteId") String siteId) {

        ShopVo vo = orderBaseService.DayRecommend(siteId);
        return Result.OK(vo);
    }


    @IgnoreAuth
    @AutoLog(value = "店铺详情")
    @ApiOperation(value = "店铺详情", notes = "id:门店的id ")
    @PostMapping(value = "/getShopInfo")
    public Result<?> getShopInfo(@RequestBody ShopInfoVo shopInfoVo) {
        return orderBaseService.getShopInfo(shopInfoVo);
    }

    @IgnoreAuth
    @AutoLog(value = "店铺内商品列表")
    @ApiOperation(value = "店铺内商品列表", notes = "id:门店的id,分类id ")
    @GetMapping(value = "/getShopOfGoodsList")
    public Result<?> getShopOfGoodsList(GoodsBasic goodsBasic,
                                        @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                        @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize) {

        return Result.OK(orderBaseService.getShopOfGoodsList(goodsBasic, pageNo, pageSize));
    }


    @AutoLog(value = "订单不展示(页面删除)")
    @ApiOperation(value = "订单不展示(页面删除)", notes = "订单id")
    @PostMapping(value = "/updOrderIsShow")
    public Result<?> updOrderIsShow(@RequestBody OrderBase orderBase) {

        if (oConvertUtils.isEmpty(orderBase.getId())) {
            return Result.error("参数错误~");
        }
        return orderBaseService.updOrderIsShow(orderBase.getId());
    }

    /*@AutoLog(value = "添加购物车")
    @ApiOperation(value = "添加购物车", response = MemberCart.class)
    @PostMapping(value = "/addMemberCart")
    public Result<?> addMemberCart(@RequestBody MemberCart memberCart) {
        Member member = verifyUserForApp();
        if (!member.getId().equals(memberCart.getMemberId())) {
            return Result.error("参数错误~");
        }
        return shopCartService.add(memberCart);
    }

    @AutoLog(value = "我的购物车")
    @ApiOperation(value = "我的购物车", response = MemberCart.class)
    @PostMapping(value = "/memberCartList")
    public Result<?> memberCartList(@RequestBody MemberCart memberCart) {
        Member member = verifyUserForApp();
        if (!member.getId().equals(memberCart.getMemberId())) {
            return Result.error("参数错误~");
        }
        if (oConvertUtils.isEmpty(memberCart.getShopId())) {
            return Result.error("参数错误~");
        }
        List<MemberCart> memberCartList = shopCartService.list(new QueryWrapper<MemberCart>()
                .eq("member_id", memberCart.getMemberId())
                .eq("shop_id", memberCart.getShopId()));
        return Result.OK(memberCartList);
    }

    @AutoLog(value = "修改购物车")
    @ApiOperation(value = "修改购物车", response = MemberCart.class)
    @PostMapping(value = "/updMemberCart")
    public Result<?> updMemberCart(@RequestBody MemberCart memberCart) {
        Member member = verifyUserForApp();
        if (!member.getId().equals(memberCart.getMemberId()) || null == memberCart.getId() || memberCart.getId().isEmpty()) {
            return Result.error("操作失败~");
        }

        return Result.OK(shopCartService.updateById(memberCart));
    }

    @AutoLog(value = "删除购物车")
    @ApiOperation(value = "删除购物车", response = MemberCart.class)
    @GetMapping(value = "/delMemberCart")
    public Result<?> delMemberCart(@RequestParam("id") String id) {
        Member member = verifyUserForApp();
        MemberCart memberCart = shopCartService.getById(id);
        if (null == memberCart || !member.getId().equals(memberCart.getMemberId())
                || null == memberCart.getId() || memberCart.getId().isEmpty()) {
            return Result.error("操作失败~");
        }
        return Result.OK(shopCartService.updateById(memberCart));
    }*/

    /**
     * 获取用户的地址列表
     *
     * @param memberId
     * @return
     */
    @AutoLog(value = "获取用户的地址列表")
    @ApiOperation(value = "获取用户的地址列表", notes = "params: memberId")
    @GetMapping(value = "/getMemberAddresses")
    public Result<?> getMemberAddresses(@RequestParam("memberId") String memberId) {
        Member member = verifyUserForApp();
        if (!memberId.equals(member.getId())) {
            return Result.error("参数错误~");
        }
        List<MemberAddress> memberAddressList = memberAddressService.getUserAddresses(memberId);
        return Result.OK(memberAddressList);
    }

    /**
     * 获取订单状态
     *
     * @param orderId
     * @return
     */
    @AutoLog(value = "获取订单状态")
    @ApiOperation(value = "获取订单状态", notes = "params: orderId")
    @GetMapping(value = "/getOrderStatusInfo")
    public Result<?> getOrderStatusInfo(@RequestParam("orderId") String orderId) {
        return Result.OK(orderBaseService.getOrderStatusInfo(orderId));
    }

    /**
     * 获取订单状态-商家端
     *
     * @param orderId
     * @return
     */
    @IgnoreAuth
    @AutoLog(value = "获取订单状态-商家端")
    @ApiOperation(value = "获取订单状态-商家端", notes = "params: orderId")
    @GetMapping(value = "/getOrderStatusInfoForMerchant")
    public Result<?> getOrderStatusInfoForMerchant(@RequestParam("orderId") String orderId) {
        return Result.OK(orderBaseService.getOrderStatusInfo(orderId));
    }

    /**
     * 添加
     *
     * @param memberAddress
     * @return
     */
    @AutoLog(value = "用户地址管理表-添加")
    @ApiOperation(value = "用户地址管理表-添加", notes = "用户地址管理表-添加")
    @PostMapping(value = "/addMemberAddress")
    public Result<?> addMemberAddress(@RequestBody MemberAddress memberAddress) {
        Member member = verifyUserForApp();
        if (!memberAddress.getMemberId().equals(member.getId())) {
            return Result.error("参数错误~");
        }
        memberAddress.setCreateBy(member.getUserName());
        memberAddress.setCreateTime(new Date());
        memberAddressService.save(memberAddress);
        return Result.OK("添加成功！");
    }

    /**
     * 编辑
     *
     * @param memberAddress
     * @return
     */
    @AutoLog(value = "用户地址管理表-编辑")
    @ApiOperation(value = "用户地址管理表-编辑", notes = "用户地址管理表-编辑")
    @PutMapping(value = "/editMemberAddress")
    public Result<?> editMemberAddress(@RequestBody MemberAddress memberAddress) {
        Member member = verifyUserForApp();
        if (!memberAddress.getMemberId().equals(member.getId())) {
            return Result.error("参数错误~");
        }
        memberAddress.setUpdateBy(member.getUserName());
        memberAddress.setUpdateTime(new Date());
        memberAddressService.updateById(memberAddress);
        return Result.OK("编辑成功!");
    }

    /**
     * 通过id删除
     *
     * @param id
     * @return
     */
    @AutoLog(value = "用户地址管理表-通过id删除")
    @ApiOperation(value = "用户地址管理表-通过id删除", notes = "用户地址管理表-通过id删除")
    @DeleteMapping(value = "/deleteMemberAddress")
    public Result<?> deleteMemberAddress(@RequestParam(name = "id", required = true) String id) {
        Member member = verifyUserForApp();
        MemberAddress memberAddress = memberAddressService.getById(id);
        if (null == memberAddress) {
            return Result.error("参数错误~");
        }
        if (!member.getId().equals(memberAddress.getMemberId())) {
            return Result.error("参数错误~");
        }
        memberAddressService.removeById(id);
        return Result.OK("删除成功!");
    }

    /**
     * 测试打印
     */
    @ApiOperation(value = "测试打印", notes = "测试打印")
    @PostMapping(value = "/testPrint")
    public Result<String> testPrint(@RequestParam(name = "orderNo", required = false) String orderNo) {
        orderBaseService.testPrint(orderNo);
        return Result.OK("测试打印");
    }

    /**
     * 根据跑腿6.0 sid 获取订单商品信息
     *
     * @param ccptOrderSid 跑腿6.0 sid
     * @return 订单商品信息
     */
    @IgnoreAuth
    @GetMapping(value = "/getOrderLine")
    public Result<List<OrderLine>> getOrderLineByCcptOrderSid(@RequestParam Integer ccptOrderSid) {
        return Result.OK(orderBaseService.getOrderLineByCcptOrderSid(ccptOrderSid));
    }

    /**
     * 根据跑腿6.0 sid 获取订单餐号
     *
     * @param ccptOrderSid 跑腿6.0 sid
     * @return 订单商品信息
     */
    @IgnoreAuth
    @GetMapping(value = "/getMealNumber")
    public Result<Integer> getMealNumberByCcptOrderSid(@RequestParam Integer ccptOrderSid) {
        return Result.OK(orderBaseService.getMealNumberByCcptOrderSid(ccptOrderSid));
    }

}
